﻿using System;
using System.Threading;
using Mono.Cecil.Metadata;
using Mono.Collections.Generic;

namespace Mono.Cecil
{
	// Token: 0x020000DA RID: 218
	public class TypeReference : MemberReference, IGenericParameterProvider, IMetadataTokenProvider, IGenericContext
	{
		// Token: 0x1700027D RID: 637
		// (get) Token: 0x060008C3 RID: 2243 RVA: 0x0001FCFC File Offset: 0x0001DEFC
		// (set) Token: 0x060008C4 RID: 2244 RVA: 0x00025F44 File Offset: 0x00024144
		public override string Name
		{
			get
			{
				return base.Name;
			}
			set
			{
				bool flag = base.IsWindowsRuntimeProjection && value != base.Name;
				if (flag)
				{
					throw new InvalidOperationException("Projected type reference name can't be changed.");
				}
				base.Name = value;
				this.ClearFullName();
			}
		}

		// Token: 0x1700027E RID: 638
		// (get) Token: 0x060008C5 RID: 2245 RVA: 0x00025F88 File Offset: 0x00024188
		// (set) Token: 0x060008C6 RID: 2246 RVA: 0x00025FA0 File Offset: 0x000241A0
		public virtual string Namespace
		{
			get
			{
				return this.@namespace;
			}
			set
			{
				bool flag = base.IsWindowsRuntimeProjection && value != this.@namespace;
				if (flag)
				{
					throw new InvalidOperationException("Projected type reference namespace can't be changed.");
				}
				this.@namespace = value;
				this.ClearFullName();
			}
		}

		// Token: 0x1700027F RID: 639
		// (get) Token: 0x060008C7 RID: 2247 RVA: 0x00025FE4 File Offset: 0x000241E4
		// (set) Token: 0x060008C8 RID: 2248 RVA: 0x000053E6 File Offset: 0x000035E6
		public virtual bool IsValueType
		{
			get
			{
				return this.value_type;
			}
			set
			{
				this.value_type = value;
			}
		}

		// Token: 0x17000280 RID: 640
		// (get) Token: 0x060008C9 RID: 2249 RVA: 0x00025FFC File Offset: 0x000241FC
		public override ModuleDefinition Module
		{
			get
			{
				bool flag = this.module != null;
				ModuleDefinition result;
				if (flag)
				{
					result = this.module;
				}
				else
				{
					TypeReference declaringType = this.DeclaringType;
					bool flag2 = declaringType != null;
					if (flag2)
					{
						result = declaringType.Module;
					}
					else
					{
						result = null;
					}
				}
				return result;
			}
		}

		// Token: 0x17000281 RID: 641
		// (get) Token: 0x060008CA RID: 2250 RVA: 0x00026040 File Offset: 0x00024240
		// (set) Token: 0x060008CB RID: 2251 RVA: 0x000038BC File Offset: 0x00001ABC
		internal TypeReferenceProjection WindowsRuntimeProjection
		{
			get
			{
				return (TypeReferenceProjection)this.projection;
			}
			set
			{
				this.projection = value;
			}
		}

		// Token: 0x17000282 RID: 642
		// (get) Token: 0x060008CC RID: 2252 RVA: 0x00020A50 File Offset: 0x0001EC50
		IGenericParameterProvider IGenericContext.Type
		{
			get
			{
				return this;
			}
		}

		// Token: 0x17000283 RID: 643
		// (get) Token: 0x060008CD RID: 2253 RVA: 0x00026060 File Offset: 0x00024260
		IGenericParameterProvider IGenericContext.Method
		{
			get
			{
				return null;
			}
		}

		// Token: 0x17000284 RID: 644
		// (get) Token: 0x060008CE RID: 2254 RVA: 0x00026074 File Offset: 0x00024274
		GenericParameterType IGenericParameterProvider.GenericParameterType
		{
			get
			{
				return GenericParameterType.Type;
			}
		}

		// Token: 0x17000285 RID: 645
		// (get) Token: 0x060008CF RID: 2255 RVA: 0x00026088 File Offset: 0x00024288
		public virtual bool HasGenericParameters
		{
			get
			{
				return !this.generic_parameters.IsNullOrEmpty<GenericParameter>();
			}
		}

		// Token: 0x17000286 RID: 646
		// (get) Token: 0x060008D0 RID: 2256 RVA: 0x000260A8 File Offset: 0x000242A8
		public virtual Collection<GenericParameter> GenericParameters
		{
			get
			{
				bool flag = this.generic_parameters == null;
				if (flag)
				{
					Interlocked.CompareExchange<Collection<GenericParameter>>(ref this.generic_parameters, new GenericParameterCollection(this), null);
				}
				return this.generic_parameters;
			}
		}

		// Token: 0x17000287 RID: 647
		// (get) Token: 0x060008D1 RID: 2257 RVA: 0x000260E0 File Offset: 0x000242E0
		// (set) Token: 0x060008D2 RID: 2258 RVA: 0x00026110 File Offset: 0x00024310
		public virtual IMetadataScope Scope
		{
			get
			{
				TypeReference declaringType = this.DeclaringType;
				bool flag = declaringType != null;
				IMetadataScope result;
				if (flag)
				{
					result = declaringType.Scope;
				}
				else
				{
					result = this.scope;
				}
				return result;
			}
			set
			{
				TypeReference declaringType = this.DeclaringType;
				bool flag = declaringType != null;
				if (flag)
				{
					bool flag2 = base.IsWindowsRuntimeProjection && value != declaringType.Scope;
					if (flag2)
					{
						throw new InvalidOperationException("Projected type scope can't be changed.");
					}
					declaringType.Scope = value;
				}
				else
				{
					bool flag3 = base.IsWindowsRuntimeProjection && value != this.scope;
					if (flag3)
					{
						throw new InvalidOperationException("Projected type scope can't be changed.");
					}
					this.scope = value;
				}
			}
		}

		// Token: 0x17000288 RID: 648
		// (get) Token: 0x060008D3 RID: 2259 RVA: 0x0002618C File Offset: 0x0002438C
		public bool IsNested
		{
			get
			{
				return this.DeclaringType != null;
			}
		}

		// Token: 0x17000289 RID: 649
		// (get) Token: 0x060008D4 RID: 2260 RVA: 0x000261A8 File Offset: 0x000243A8
		// (set) Token: 0x060008D5 RID: 2261 RVA: 0x000261C0 File Offset: 0x000243C0
		public override TypeReference DeclaringType
		{
			get
			{
				return base.DeclaringType;
			}
			set
			{
				bool flag = base.IsWindowsRuntimeProjection && value != base.DeclaringType;
				if (flag)
				{
					throw new InvalidOperationException("Projected type declaring type can't be changed.");
				}
				base.DeclaringType = value;
				this.ClearFullName();
			}
		}

		// Token: 0x1700028A RID: 650
		// (get) Token: 0x060008D6 RID: 2262 RVA: 0x00026204 File Offset: 0x00024404
		public override string FullName
		{
			get
			{
				bool flag = this.fullname != null;
				string result;
				if (flag)
				{
					result = this.fullname;
				}
				else
				{
					string text = this.TypeFullName();
					bool isNested = this.IsNested;
					if (isNested)
					{
						text = this.DeclaringType.FullName + "/" + text;
					}
					Interlocked.CompareExchange<string>(ref this.fullname, text, null);
					result = this.fullname;
				}
				return result;
			}
		}

		// Token: 0x1700028B RID: 651
		// (get) Token: 0x060008D7 RID: 2263 RVA: 0x00009C40 File Offset: 0x00007E40
		public virtual bool IsByReference
		{
			get
			{
				return false;
			}
		}

		// Token: 0x1700028C RID: 652
		// (get) Token: 0x060008D8 RID: 2264 RVA: 0x00009C40 File Offset: 0x00007E40
		public virtual bool IsPointer
		{
			get
			{
				return false;
			}
		}

		// Token: 0x1700028D RID: 653
		// (get) Token: 0x060008D9 RID: 2265 RVA: 0x00009C40 File Offset: 0x00007E40
		public virtual bool IsSentinel
		{
			get
			{
				return false;
			}
		}

		// Token: 0x1700028E RID: 654
		// (get) Token: 0x060008DA RID: 2266 RVA: 0x00009C40 File Offset: 0x00007E40
		public virtual bool IsArray
		{
			get
			{
				return false;
			}
		}

		// Token: 0x1700028F RID: 655
		// (get) Token: 0x060008DB RID: 2267 RVA: 0x00009C40 File Offset: 0x00007E40
		public virtual bool IsGenericParameter
		{
			get
			{
				return false;
			}
		}

		// Token: 0x17000290 RID: 656
		// (get) Token: 0x060008DC RID: 2268 RVA: 0x00009C40 File Offset: 0x00007E40
		public virtual bool IsGenericInstance
		{
			get
			{
				return false;
			}
		}

		// Token: 0x17000291 RID: 657
		// (get) Token: 0x060008DD RID: 2269 RVA: 0x00009C40 File Offset: 0x00007E40
		public virtual bool IsRequiredModifier
		{
			get
			{
				return false;
			}
		}

		// Token: 0x17000292 RID: 658
		// (get) Token: 0x060008DE RID: 2270 RVA: 0x00009C40 File Offset: 0x00007E40
		public virtual bool IsOptionalModifier
		{
			get
			{
				return false;
			}
		}

		// Token: 0x17000293 RID: 659
		// (get) Token: 0x060008DF RID: 2271 RVA: 0x00009C40 File Offset: 0x00007E40
		public virtual bool IsPinned
		{
			get
			{
				return false;
			}
		}

		// Token: 0x17000294 RID: 660
		// (get) Token: 0x060008E0 RID: 2272 RVA: 0x00009C40 File Offset: 0x00007E40
		public virtual bool IsFunctionPointer
		{
			get
			{
				return false;
			}
		}

		// Token: 0x17000295 RID: 661
		// (get) Token: 0x060008E1 RID: 2273 RVA: 0x00026268 File Offset: 0x00024468
		public virtual bool IsPrimitive
		{
			get
			{
				return this.etype.IsPrimitive();
			}
		}

		// Token: 0x17000296 RID: 662
		// (get) Token: 0x060008E2 RID: 2274 RVA: 0x00026288 File Offset: 0x00024488
		public virtual MetadataType MetadataType
		{
			get
			{
				ElementType elementType = this.etype;
				ElementType elementType2 = elementType;
				MetadataType result;
				if (elementType2 != ElementType.None)
				{
					result = (MetadataType)this.etype;
				}
				else
				{
					result = (this.IsValueType ? MetadataType.ValueType : MetadataType.Class);
				}
				return result;
			}
		}

		// Token: 0x060008E3 RID: 2275 RVA: 0x000053F0 File Offset: 0x000035F0
		protected TypeReference(string @namespace, string name) : base(name)
		{
			this.@namespace = (@namespace ?? string.Empty);
			this.token = new MetadataToken(TokenType.TypeRef, 0);
		}

		// Token: 0x060008E4 RID: 2276 RVA: 0x00005423 File Offset: 0x00003623
		public TypeReference(string @namespace, string name, ModuleDefinition module, IMetadataScope scope) : this(@namespace, name)
		{
			this.module = module;
			this.scope = scope;
		}

		// Token: 0x060008E5 RID: 2277 RVA: 0x0000543E File Offset: 0x0000363E
		public TypeReference(string @namespace, string name, ModuleDefinition module, IMetadataScope scope, bool valueType) : this(@namespace, name, module, scope)
		{
			this.value_type = valueType;
		}

		// Token: 0x060008E6 RID: 2278 RVA: 0x00005455 File Offset: 0x00003655
		protected virtual void ClearFullName()
		{
			this.fullname = null;
		}

		// Token: 0x060008E7 RID: 2279 RVA: 0x0001C204 File Offset: 0x0001A404
		public virtual TypeReference GetElementType()
		{
			return this;
		}

		// Token: 0x060008E8 RID: 2280 RVA: 0x000262C0 File Offset: 0x000244C0
		protected override IMemberDefinition ResolveDefinition()
		{
			return this.Resolve();
		}

		// Token: 0x060008E9 RID: 2281 RVA: 0x000262D8 File Offset: 0x000244D8
		public new virtual TypeDefinition Resolve()
		{
			ModuleDefinition moduleDefinition = this.Module;
			bool flag = moduleDefinition == null;
			if (flag)
			{
				throw new NotSupportedException();
			}
			return moduleDefinition.Resolve(this);
		}

		// Token: 0x0400036F RID: 879
		private string @namespace;

		// Token: 0x04000370 RID: 880
		private bool value_type;

		// Token: 0x04000371 RID: 881
		internal IMetadataScope scope;

		// Token: 0x04000372 RID: 882
		internal ModuleDefinition module;

		// Token: 0x04000373 RID: 883
		internal ElementType etype = ElementType.None;

		// Token: 0x04000374 RID: 884
		private string fullname;

		// Token: 0x04000375 RID: 885
		protected Collection<GenericParameter> generic_parameters;
	}
}
